function spreadLayout(cache, dataList) {
    let data = cache.data;
    let children = [];

    for (var i = 0; i < dataList.length; i++) {
        if (isParent(data, dataList[i])) {
            let child = getCache(dataList[i]);
            if (!child.parent && cache.index < child.index) {
                children.push(dataList[i]);
            }
        }
    }

    children = children.filter(function (item) {
        let type = figure(item);

        if (type == "Container") {
            if (!item.fills) {
                return false;
            }
            let color = getContainerColor(item);
            if (color.length == 0 && !(item.fills[item.fills.length - 1]).gradient) {
                return false;
            }

            for (var i = 0; i < dataList.length; i++) {
                let other = dataList[i];
                let otherCache = getCache(other);
                if (isParent(other, data) && cache.index > otherCache.index) {
                    let parentType = figure(other);
                    if (parentType == "Container") {
                        let parentColor = getContainerColor(other);
                        if (color == parentColor) {
                            return false;
                        }
                    }
                }
            }
        }


        return type != "SizedBox";
    });

    let layout = preLayout(cache, children);
    setupLevel(cache.data, layout.data);

    return cache;
}

function preLayout(cache, childDatas) {
    for (let i = 0; i < childDatas.length; i++) {
        let a = childDatas[i];
        let aCache = getCache(a);
        let parent = findParent(aCache, childDatas);
        if (parent && cache != parent) {
            setupLevel(parent, a);
        }
    }

    childDatas = childDatas.filter(function (item) {
        let cache = getCache(item);
        let type = figure(item);
        let hasChildren = (cache.children && cache.children.length > 0) || false;
        let isGroup = type == "SizedBox" && hasChildren;
        return (!cache.parent && type != "SizedBox") || isGroup;
    });

    genRelative(childDatas);
    return spreadBrothers(childDatas);
}

function genRelative(childDatas) {
    for (let i = 0; i < childDatas.length; i++) {
        let a = childDatas[i];
        let aCache = getCache(a);
        newRelative(aCache);

        for (let j = i + 1; j < childDatas.length; j++) {
            let b = childDatas[j];
            let bCache = getCache(b);
            newRelative(bCache);

            if (isIntersect(a, b)) {
                if (aCache.index < bCache.index) {
                    bCache.relative.isFloat = true;
                } else {
                    aCache.relative.isFloat = true;
                }
            } else {
                // 非重叠情况下判断ab的相对位置
                if (isYIntersect(a, b)) {
                    if (a.x + a.width < b.x) {
                        aCache.relative.right.push(bCache);
                        bCache.relative.left.push(aCache);
                    } else {
                        aCache.relative.left.push(bCache);
                        bCache.relative.right.push(aCache);
                    }
                } else if (isXIntersect(a, b)) {
                    if (a.y + a.height < b.y) {
                        aCache.relative.bottom.push(bCache);
                        bCache.relative.top.push(aCache);
                    } else {
                        aCache.relative.top.push(bCache);
                        bCache.relative.bottom.push(aCache);
                    }
                } else {
                    console.log("完全不关联", a.id, b.id);
                }
            }
        }
    }

    for (let i = 0; i < childDatas.length; i++) {
        let data = childDatas[i];
        let cache = getCache(data);
        cache.relative.left = cache.relative.left.filter(function (item) {
            return !item.relative.isFloat;
        });
        if (cache.relative.left.length > 0) {
            cache.relative.left.sort(function (a, b) {
                return b.x - a.x;
            });

            cache.relative.leftBro = [];

            for (let j = 0; j < cache.relative.left.length; j++) {
                let item = cache.relative.left[j].data;
                let valid = true;
                for (let k = 0; k < cache.relative.leftBro.length; k++) {
                    let bro = cache.relative.leftBro[k];
                    // x、y轴重合且更贴近
                    if ((item.x > bro.data.x + bro.data.width) && isYIntersect(item, bro.data)) {
                        bro.valid = false;
                    } else if (!isYIntersect(item, bro.data)) {
                        continue;
                    } else {
                        valid = false;
                        break;
                    }
                }
                if (valid) {
                    cache.relative.leftBro = cache.relative.leftBro.filter(function (item) {
                        return item.valid;
                    })
                    cache.relative.leftBro.push({
                        data: item,
                        valid: true
                    });
                }
            }
        }

        cache.relative.right = cache.relative.right.filter(function (item) {
            return !item.relative.isFloat;
        });
        if (cache.relative.right.length > 0) {
            cache.relative.right.sort(function (a, b) {
                return a.x - b.x;
            });

            cache.relative.rightBro = [];

            for (let j = 0; j < cache.relative.right.length; j++) {
                let item = cache.relative.right[j].data;
                let valid = true;
                for (let k = 0; k < cache.relative.rightBro.length; k++) {
                    let bro = cache.relative.rightBro[k];
                    // x、y轴重合且更贴近
                    if ((item.x + item.width < bro.data.x) && isYIntersect(item, bro.data)) {
                        bro.valid = false;
                    } else if (!isYIntersect(item, bro.data)) {
                        continue;
                    } else {
                        valid = false;
                        break;
                    }
                }
                if (valid) {
                    cache.relative.rightBro = cache.relative.rightBro.filter(function (item) {
                        return item.valid;
                    })
                    cache.relative.rightBro.push({
                        data: item,
                        valid: true
                    });
                }
            }
        }


        cache.relative.top = cache.relative.top.filter(function (item) {
            return !item.relative.isFloat;
        });
        if (cache.relative.top.length > 0) {
            cache.relative.top.sort(function (a, b) {
                return b.y - a.y;
            });

            cache.relative.topBro = [];

            for (let j = 0; j < cache.relative.top.length; j++) {
                let item = cache.relative.top[j].data;
                let valid = true;
                for (let k = 0; k < cache.relative.topBro.length; k++) {
                    let bro = cache.relative.topBro[k];
                    // x、y轴重合且更贴近
                    if ((item.y > bro.data.y + bro.data.height) && isXIntersect(item, bro.data)) {
                        bro.valid = false;
                    } else if (!isXIntersect(item, bro.data)) {
                        continue;
                    } else {
                        valid = false;
                        break;
                    }
                }
                if (valid) {
                    cache.relative.topBro = cache.relative.topBro.filter(function (item) {
                        return item.valid;
                    })
                    cache.relative.topBro.push({
                        data: item,
                        valid: true
                    });
                }
            }
        }

        cache.relative.bottom = cache.relative.bottom.filter(function (item) {
            return !item.relative.isFloat;
        });
        if (cache.relative.bottom.length > 0) {
            cache.relative.bottom.sort(function (a, b) {
                return a.y - b.y;
            });

            cache.relative.bottomBro = [];

            for (let j = 0; j < cache.relative.bottom.length; j++) {
                let item = cache.relative.bottom[j].data;
                let valid = true;
                for (let k = 0; k < cache.relative.bottomBro.length; k++) {
                    let bro = cache.relative.bottomBro[k];
                    // x、y轴重合且更贴近
                    if ((item.y + item.height < bro.data.y) && isXIntersect(item, bro.data)) {
                        bro.valid = false;
                    } else if (!isXIntersect(item, bro.data)) {
                        continue;
                    } else {
                        valid = false;
                        break;
                    }
                }
                if (valid) {
                    cache.relative.bottomBro = cache.relative.bottomBro.filter(function (item) {
                        return item.valid;
                    })
                    cache.relative.bottomBro.push({
                        data: item,
                        valid: true
                    });
                }
            }
        }
    }
}

function newRelative(cache) {
    cache.relative = cache.relative || {
        left: [],
        right: [],
        top: [],
        bottom: [],
        isFloat: false
    };
}

function spreadBrothers(childDatas) {
    childDatas.sort(function (a, b) {
        return a.x - b.x;
    })

    for (let i = 0; i < childDatas.length; i++) {
        let data = childDatas[i];
        let cache = getCache(data);
        let relative = cache.relative;

        if (onlyOne(relative.leftBro) && (!cache.parent || (cache.parent.type == "Row"))) {
            let leftBro = getCache(relative.leftBro[0].data);
            if (!leftBro.parent && onlyOne(leftBro.relative.rightBro) && leftBro.relative.rightBro[0].data == data) {
                let parent = cache.parent || newVirtual();
                setupLevel(parent.data, data);
                setupLevel(parent.data, leftBro.data);
                parent.type = "Row";
            }
        }

        if (onlyOne(relative.rightBro) && (!cache.parent || (cache.parent.type == "Row"))) {
            let rightBro = getCache(relative.rightBro[0].data);
            if (!rightBro.parent && onlyOne(rightBro.relative.leftBro) && rightBro.relative.leftBro[0].data == data) {
                let parent = cache.parent || newVirtual();
                setupLevel(parent.data, data);
                setupLevel(parent.data, rightBro.data);
                parent.type = "Row";
            }
        }
    }

    childDatas.sort(function (a, b) {
        return a.y - b.y;
    })

    for (let i = 0; i < childDatas.length; i++) {
        let data = childDatas[i];
        let cache = getCache(data);
        let relative = cache.relative;

        if (onlyOne(relative.topBro) && (!cache.parent || (cache.parent.type == "Column"))) {
            let topBro = getCache(relative.topBro[0].data);
            if (!topBro.parent && onlyOne(topBro.relative.bottomBro) && topBro.relative.bottomBro[0].data == data) {
                let parent = cache.parent || newVirtual();
                setupLevel(parent.data, data);
                setupLevel(parent.data, topBro.data);
                parent.type = "Column";
            }
        }

        if (onlyOne(relative.bottomBro) && (!cache.parent || (cache.parent.type == "Column"))) {
            let bottomBro = getCache(relative.bottomBro[0].data);
            if (!bottomBro.parent && onlyOne(bottomBro.relative.topBro) && bottomBro.relative.topBro[0].data == data) {
                let parent = cache.parent || newVirtual();
                setupLevel(parent.data, data);
                setupLevel(parent.data, bottomBro.data);
                parent.type = "Column";
            }
        }
    }

    let virtualParent = new Set();
    for (let i = 0; i < childDatas.length; i++) {
        let data = childDatas[i];
        let cache = getCache(data);
        if (cache.parent && cache.parent.isVirtual) {
            virtualParent.add(cache.parent);
        }
    }

    let next = childDatas.filter(function (item) {
        let cache = getCache(item);
        return !cache.parent
    })

    virtualParent.forEach(function (item) {
        fixLayoutSize(item);
        next.push(item.data);
    });

    console.log("next.length", next.length, "lastCount", childDatas.length);
    if (childDatas.length == next.length) {
        // 检查是否有浮层
        for (let i = 0; i < next.length; i++) {
            let cache = getCache(next[i]);
            if (cache.relative.isFloat) {
                console.log("有浮层", cache.id);
            }
        }

        let stack = newVirtual();
        for (let i = 0; i < next.length; i++) {
            setupLevel(stack.data, next[i]);
        }
        fixLayoutSize(stack);
        return stack;
    } else if (next.length > 1) {
        for (let i = 0; i < next.length; i++) {
            let item = next[i];
            let cache = getCache(item);
            cache.relative = null;
        }
        genRelative(next);
        return spreadBrothers(next);
    } else {
        return getCache(next[0]);
    }
}

function onlyOne(list) {
    return list && list.length == 1;
}